﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DirectCanvas;
using DirectCanvas.Imaging;
using DirectCanvas.Misc;
using WindowsFormsTest.Demos.GPGPU.Effects;
using DirectCanvas.Scenes;

namespace WindowsFormsTest.Demos.GPGPU
{
    class GPGPUScene : Scene
    {
        private readonly Presenter m_presenter;
        DrawingLayer m_workingLayer;
        DrawingLayer m_tempLayer;
        Image m_data1Image;
        private GPGPUEffect m_gpgpuEffect;

        const int width = 500;
        const int height = 500;

        static Random random = new Random();

        public GPGPUScene(Presenter presenter)
        {
            m_presenter = presenter;

            m_tempLayer = presenter.Factory.CreateDrawingLayer(width, height);
            m_workingLayer = presenter.Factory.CreateDrawingLayer(width, height);
            m_tempLayer.EnableImageCopy = true;
            m_workingLayer.EnableImageCopy = true;
            m_data1Image = presenter.Factory.CreateImage(@".\Assets\Nature Mountains photo.jpg");
            //m_data1Image = presenter.Factory.CreateImage(width, height);
            
            m_gpgpuEffect = new GPGPUEffect(presenter.Factory);

            //LoadData(m_data1Image);
        }

        public override void Render()
        {
            m_tempLayer.CopyFromImage(m_data1Image);

            m_gpgpuEffect.Sigma = 2f;
            m_gpgpuEffect.Tint = new Color4(1, 1, 1, 1);
            m_gpgpuEffect.MinThreshold = 0.05f;
            m_gpgpuEffect.SampleSize = new SizeF(width / 2, height / 2);

            m_tempLayer.ApplyEffect(m_gpgpuEffect, m_workingLayer);
            
            m_presenter.BeginDraw();
            //m_presenter.DrawLayer(m_tempLayer);
            m_presenter.DrawLayer(m_workingLayer);

            m_presenter.EndDraw();
        }

        private unsafe void LoadData(Image image)
        {            
            var imageData = image.Lock(ImageLock.ReadWrite);

            byte* data = (byte*)imageData.Scan0.ToPointer();

            for (int i = 0; i < imageData.BufferSize; i+=4)
            {
                byte value = (byte)((double)i*255 / (double)imageData.BufferSize);
                for (int k = 0; k < 3; k++)
                {
                    if (i+k < imageData.BufferSize)
                        data[i + k] = value;
                }
                data[i + 3] = 255;
            }

            image.Unlock(imageData);
        }
    }
}
